#include <stdarg.h> // 提供 va_list、va_start、va_arg、va_end

// 底层字符输出函数（需根据硬件实现）
void uart_putc(char c) {
    // 示例：假设串口寄存器地址为 0x10000000
    volatile unsigned char *uart = (volatile unsigned char *)0x10000000;
    *uart = c; // 发送字符到串口
}

// 输出字符串的辅助函数
void uart_puts(const char *s) {
    while (*s) {
        uart_putc(*s++);
    }
}

// 将整数转换为字符串（支持不同进制）
void itoa(int num, char *buf, int base) {
    char *digits = "0123456789ABCDEF";
    char temp[32];
    int i = 0;
    int is_negative = 0;

    // 处理负数（仅十进制）
    if (num < 0 && base == 10) {
        is_negative = 1;
        num = -num;
    }

    // 转换为字符串（倒序）
    do {
        temp[i++] = digits[num % base];
        num /= base;
    } while (num > 0);

    // 添加负号
    if (is_negative) {
        temp[i++] = '-';
    }

    // 反转到 buf
    int j = 0;
    while (i > 0) {
        buf[j++] = temp[--i];
    }
    buf[j] = '\0';
}

// 自定义 printf 函数
void my_printf(const char *fmt, ...) {
    va_list args;
    va_start(args, fmt); // 初始化可变参数列表
    char buf[32];        // 缓冲区，用于数字转换

    while (*fmt) {
        if (*fmt != '%') {
            // 普通字符直接输出
            uart_putc(*fmt);
            fmt++;
            continue;
        }

        // 处理格式说明符
        fmt++; // 跳过 '%'
        switch (*fmt) {
            case 'c': { // 字符
                char c = (char)va_arg(args, int); // char 被提升为 int
                uart_putc(c);
                break;
            }
            case 's': { // 字符串
                const char *s = va_arg(args, const char *);
                uart_puts(s);
                break;
            }
            case 'd': { // 十进制整数
                int num = va_arg(args, int);
                itoa(num, buf, 10);
                uart_puts(buf);
                break;
            }
            case 'x': { // 十六进制整数
                int num = va_arg(args, int);
                itoa(num, buf, 16);
                uart_puts(buf);
                break;
            }
            case '%': { // 字面量 '%'
                uart_putc('%');
                break;
            }
            default: { // 未识别的格式，输出原字符
                uart_putc(*fmt);
                break;
            }
        }
        fmt++;
    }

    va_end(args); // 清理可变参数
}